package com.guptarulie.jmeter.protocol.mm7.deliveryrequest.control;

import java.io.InterruptedIOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;

/**
 * Server daemon thread.
 * Creates main socket and listens on it.
 * For each client request, creates a thread to handle the request.
 *
 */
public class MM7DeliveryRequestReceiverServer extends Thread {
    private static final Logger log = LoggingManager.getLoggerForClass();

    /**
     * The time (in milliseconds) to wait when accepting a client connection.
     * The accept will be retried until the Daemon is told to stop. So this
     * interval is the longest time that the Daemon will have to wait after
     * being told to stop.
     */
    private static final int ACCEPT_TIMEOUT = 1000;

    /** The port to listen on. */
    private final int daemonPort;

    /** True if the Daemon is currently running. */
    private volatile boolean running;

    // Saves the error if one occurs
    private volatile Exception except;
    
    private Object viewObj;
    
    private MM7ConfigurableParameters mm7Parameters;

    /**
     * Create a new Daemon with the specified port and target.
     *
     * @param port
     *            the port to listen on.
     */
    public MM7DeliveryRequestReceiverServer(int port, MM7ConfigurableParameters parameters, Object obj) {
        super("MM7DeliveryRequestReceiverServer");
        this.daemonPort = port;
        this.mm7Parameters = parameters;
        this.viewObj = obj;
    }

    /**
     * Listen on the daemon port and handle incoming requests. This method will
     * not exit until {@link #stopServer()} is called or an error occurs.
     */
    public void run() {
        except = null;
        running = true;
        ServerSocket mainSocket = null;

        try {
            log.info("Creating MM7DeliveryRequestReceiverServer ... on port " + daemonPort);
            mainSocket = new ServerSocket(daemonPort);
            mainSocket.setSoTimeout(ACCEPT_TIMEOUT);
            log.info("MM7DeliveryRequestReceiverServer up and running!");

            while (running) {
                try {
                    // Listen on main socket
                    Socket clientSocket = mainSocket.accept();
                    if (running) {
                    	
                        // Set the time out to 5 seconds...
                        clientSocket.setSoTimeout(15000);
                        // Pass request to new thread
                        MM7DeliveryRequestReceiverThread thd = new MM7DeliveryRequestReceiverThread(clientSocket, mm7Parameters, viewObj);
                        log.info("Starting new MM7DeliveryRequestReceiver thread");
                        thd.start();
                    } else {
                        log.warn("Server not running");
                        JOrphanUtils.closeQuietly(clientSocket);
                    }
                } catch (InterruptedIOException e) {
                    // Timeout occurred. Ignore, and keep looping until we're
                    // told to stop running.
                }
            }
            log.info("MM7DeliveryRequestReceiverServer stopped");
        } catch (Exception e) {
            except = e;
            log.warn("MM7DeliveryRequestReceiverServer stopped", e);
        } finally {
            JOrphanUtils.closeQuietly(mainSocket);
        }
    }

    public void stopServer() {
        running = false;
    }

    public Exception getException(){
        return except;
    }

    public static void main(String args[]){
        int port = 9800;
        if (args.length > 0){
            port = Integer.parseInt(args[0]);
        }
        MM7ConfigurableParameters parameters = new MM7ConfigurableParameters();
        // TODO -- fill up the values of parameters...
        MM7DeliveryRequestReceiverServer serv = new MM7DeliveryRequestReceiverServer(port, parameters, null);
        serv.start();
    }
}
